package com.legsem.jhosync.model;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.UUID;

import org.apache.commons.dbutils.ResultSetHandler;

public class Client extends Model implements ResultSetHandler < Client > {

    private static final long serialVersionUID = 1L;

    public static final String TABLE_NAME = "CLIENTS";

    public static final String SQL_CREATE = "CREATE TABLE "
            + TABLE_NAME
            + " (\n"
            + "         ID                CHAR (32),\n"
            + "         DEVICE_PIN        VARCHAR (255),\n"
            + "         DEVICE_PORT       VARCHAR (255),\n"
            + "         DEVICE_TYPE       VARCHAR (255),\n"
            + "         USER_LOGIN        VARCHAR (255),\n"
            + "         PRIMARY KEY ( ID ),\n"
            + "         FOREIGN KEY ( USER_LOGIN ) REFERENCES USERS ( LOGIN ) ON DELETE CASCADE);\n";

    public static final String SQL_DROP = "DROP TABLE " + TABLE_NAME + ";\n";

    private String id;
    private String devicePin;
    private String devicePort;
    private String deviceType;
    private String userLogin;

    public static String getSqlCreate() {
        return SQL_CREATE;
    }

    public static String getSqlDrop() {
        return SQL_DROP;
    }

    public Client() {
    }

    public Client(String userLogin) {
        this.id = UUID.randomUUID().toString().replace("-", "");
        this.userLogin = userLogin;
    }

    public static Client find(String id) throws SQLException {
        return find(id, false);
    }

    public static Client findForUpdate(String id) throws SQLException {
        return find(id, true);
    }

    public static Client find(String id, boolean forUpdate) throws SQLException {
        return run.query(getConnection(), "SELECT * FROM " + TABLE_NAME
                + " WHERE ID=?" + ((forUpdate) ? " FOR UPDATE" : ""),
                new Client(), id);
    }

    public int create() throws SQLException {
        return run.update(getConnection(), "INSERT INTO " + TABLE_NAME
                + " VALUES (?, ?, ? , ?, ?)", id, devicePin, devicePort,
                deviceType, userLogin);
    }

    public int delete() throws SQLException {
        return run.update(getConnection(), "DELETE FROM " + TABLE_NAME
                + " WHERE id=?", id);
    }

    public int update() throws SQLException {
        return run.update(getConnection(), "UPDATE " + TABLE_NAME
                + " SET DEVICE_PIN = ?," + " DEVICE_PORT = ?,"
                + " DEVICE_TYPE = ?," + " USER_LOGIN = ?" + " WHERE id=?",
                devicePin, devicePort, deviceType, userLogin, id);
    }

    public Client handle(ResultSet rs) throws SQLException {

        if (!rs.next()) {
            return null;
        }
        Client client = new Client();
        ResultSetMetaData meta = rs.getMetaData();
        int cols = meta.getColumnCount();

        for (int i = 0; i < cols; i++) {
            switch (i) {
            case 0:
                client.setId(rs.getString(i + 1));
                break;
            case 1:
                client.setDevicePin(rs.getString(i + 1));
                break;
            case 2:
                client.setDevicePort(rs.getString(i + 1));
                break;
            case 3:
                client.setDeviceType(rs.getString(i + 1));
                break;
            case 4:
                client.setUserLogin(rs.getString(i + 1));
                break;
            }
        }

        return client;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((devicePin == null) ? 0 : devicePin.hashCode());
        result = prime * result
                + ((devicePort == null) ? 0 : devicePort.hashCode());
        result = prime * result
                + ((deviceType == null) ? 0 : deviceType.hashCode());
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        result = prime * result
                + ((userLogin == null) ? 0 : userLogin.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        Client other = (Client) obj;
        if (devicePin == null) {
            if (other.devicePin != null) {
                return false;
            }
        } else if (!devicePin.equals(other.devicePin)) {
            return false;
        }
        if (devicePort == null) {
            if (other.devicePort != null) {
                return false;
            }
        } else if (!devicePort.equals(other.devicePort)) {
            return false;
        }
        if (deviceType == null) {
            if (other.deviceType != null) {
                return false;
            }
        } else if (!deviceType.equals(other.deviceType)) {
            return false;
        }
        if (id == null) {
            if (other.id != null) {
                return false;
            }
        } else if (!id.equals(other.id)) {
            return false;
        }
        if (userLogin == null) {
            if (other.userLogin != null) {
                return false;
            }
        } else if (!userLogin.equals(other.userLogin)) {
            return false;
        }
        return true;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getDevicePin() {
        return devicePin;
    }

    public void setDevicePin(String devicePin) {
        this.devicePin = devicePin;
    }

    public String getDevicePort() {
        return devicePort;
    }

    public void setDevicePort(String devicePort) {
        this.devicePort = devicePort;
    }

    public String getDeviceType() {
        return deviceType;
    }

    public void setDeviceType(String deviceType) {
        this.deviceType = deviceType;
    }

    public String getUserLogin() {
        return userLogin;
    }

    public void setUserLogin(String userLogin) {
        this.userLogin = userLogin;
    }

    @Override
    public String toString() {
        return "Client [id=" + id + ", devicePin=" + devicePin
                + ", devicePort=" + devicePort + ", deviceType=" + deviceType
                + ", userLogin=" + userLogin + "]";
    }

}
